/**
 * FileFind - ftp/shares indexing and search php engine
 * Module: agent-java
 * Description: Agent written in java language
 * Copyright (c) 2003-2010 Rage Steel, www.gt2.ru
 */
package ru.ffind.agent.db;

import java.util.logging.Level;
import java.util.logging.Logger;

import ru.ffind.common.model.Entry;
import ru.ffind.agent.model.ListingStorage;
import ru.ffind.agent.model.RootDirectory;
import ru.ffind.agent.net.NetTools;

import ru.ffind.agent.AgentConfig;
import ru.ffind.agent.dao.Dao;

/**
 *
 * Reading database structure
 *
 * @author Rage Steel
 *
 */
public class DbScanner {

	private final static Logger LOGGER = 
		Logger.getLogger(DbScanner.class.getName());
	
    private final AgentConfig agentConfig;

    private final Dao dao;

	public DbScanner(Dao dao, AgentConfig agentConfig) {
        this.dao = dao;
        this.agentConfig = agentConfig;
	}

	private DbHost host;

	/**
	 *
	 * Check host status for indexing
	 * If ready - host will be locked
	 *
	 * @return True if host is ready for indexing
	 *
	 */
	public boolean isReady() {
		host = dao.findOrCreateHost(NetTools.HOSTNAME, NetTools.IP_ADDRESS,
                agentConfig.getHostType(), agentConfig.getHostOwner());
		if (null == host) {
			throw new IllegalArgumentException("Host not found: " + NetTools.HOSTNAME);
		}

		LOGGER.log(Level.INFO, "Host found!, host_id={0}", host.getHostId());

		// Add detection isNeedCrawl
		if (!host.isCrawlNeeded()) {
			LOGGER.log(Level.INFO, "Host crawling is not needed!");
			return false;
		}

		// Add host locking
		if (!dao.lockHost(host)) {
			LOGGER.log(Level.INFO, "Unable to lock host!");
			return false;
		}

		return true;
	}

	/**
	 *
	 * Scan host directory structure stored in the database
	 * isReady method must be called before calling this method
	 *
	 * @param listingStorage Storage for the directory structure
	 *
	 */
	public void scan(ListingStorage listingStorage) {
		if (null == host) {
			throw new IllegalStateException("isReady must return true!");
		}

		// Then start getting listing from root directory
		doScan(host.getRootDirId(), listingStorage, null, RootDirectory.ROOT_NAME);

		// FIXME Unlock only on closeHost() method, after completion of sync
		dao.unlockHost(host);
	}

	private void doScan(Integer dirId, ListingStorage listingStorage, DbDirectory placeHolder, String absolutePath) {
		if (null == dirId) {
			return;
		}

		DbDirectory dir = dao.queryDirectory(dirId, placeHolder);
		listingStorage.put(absolutePath, dir);

		for (Entry entry: dir.getEntries()) {
			if (entry instanceof DbDirectory) {
				DbDirectory entryDir = (DbDirectory)entry;
				doScan(entryDir.getDirId(), listingStorage, entryDir, entryDir.getAbsPath(absolutePath));
			}
		}
	}

    /**
     * Return loaded host.
     *
     * @return
     */
	public DbHost getHost() {
		return host;
	}

}
